{{header}}

import { Contract as __Contract, Interface } from "fuels";
{{#if imports}}
import type {
  Provider,
  Account,
  StorageSlot,
  Address,
{{#each imports}}
  {{this}},
{{/each}}
} from 'fuels';
{{/if}}

{{#if commonTypesInUse}}
import type { {{commonTypesInUse}} } from "./common";
{{/if}}


{{#each enums}}
{{#if inputNativeValues}}
export enum {{structName}}Input { {{inputNativeValues}} };
{{else}}
export type {{structName}}Input{{typeAnnotations}} = Enum<{ {{inputValues}} }>;
{{/if}}
{{#if outputNativeValues}}
export enum {{structName}}Output { {{outputNativeValues}} };
{{else}}
  {{#if recycleRef}}
export type {{structName}}Output{{typeAnnotations}} = {{structName}}Input{{typeAnnotations}};
  {{else}}
export type {{structName}}Output{{typeAnnotations}} = Enum<{ {{outputValues}} }>;
  {{/if}}
{{/if}}
{{/each}}


{{#each structs}}
export type {{structName}}Input{{typeAnnotations}} = { {{inputValues}} };
{{#if recycleRef}}
export type {{structName}}Output{{typeAnnotations}} = {{structName}}Input{{typeAnnotations}};
{{else}}
export type {{structName}}Output{{typeAnnotations}} = { {{outputValues}} };
{{/if}}
{{/each}}

{{#if configurables}}
export type {{capitalizedName}}Configurables = Partial<{
{{#each configurables}}
  {{name}}: {{inputLabel}};
{{/each}}
}>;
{{/if}}

const abi = {{abiJsonString}};

const storageSlots: StorageSlot[] = {{storageSlotsJsonString}};

export class {{capitalizedName}}Interface extends Interface {
  constructor() {
    super(abi);
  }

  declare functions: {
    {{#each functionsFragments}}
    {{this}}: FunctionFragment;
    {{/each}}
  };
}

export class {{capitalizedName}} extends __Contract {
  static readonly abi = abi;
  static readonly storageSlots = storageSlots;

  declare interface: {{capitalizedName}}Interface;
  declare functions: {
    {{#each functionsTypedefs}}
    {{this}};
    {{/each}}
  };

  constructor(
    id: string | Address,
    accountOrProvider: Account | Provider,
  ) {
    super(id, abi, accountOrProvider);
  }
}
